#include "stdafx.h"

#include "Engine.h"

///////////////////////////////////////////////////////////////////////////////////////////////
/// International checkers bitboard move generator - used first 50 bits in double word
///////////////////////////////////////////////////////////////////////////////////////////////

namespace InternationalMoveGen
{
	 // Precalculating rayattacks routines for long-range kings
	////////////////////////////////////////////////////////////////////////////////////////////////
	
	uint64 rayAttacks[4][50];

	void PrecalculateRayAttacks()
	{
		uint64 gen = 0;
		uint64 result = 0;
		for(int i = 0; i < 50; i++)
		{
			// left forward
			gen = 1ull << i;
			result = 0;

			for(int j = 0; j < 10; j++)
			{
				int idx = LSB64(gen) / 5;
				gen = idx % 2 == 0 ? (gen & LF1_64) << 4 : (gen & LF2_64) << 5;
				result |= gen;
			}

			rayAttacks[0][i] = result;

			// right forward
			gen = 1ull << i;
			result = 0;

			for(int j = 0; j < 10; j++)
			{
				int idx = LSB64(gen) / 5;
				gen = idx % 2 == 0 ? (gen & RF1_64) << 5 : (gen & RF2_64) << 6;
				result |= gen;
			}

			rayAttacks[1][i] = result;

			// left backwards
			gen = 1ull << i;
			result = 0;

			for(int j = 0; j < 10; j++)
			{
				int idx = LSB64(gen) / 5;
				gen = idx % 2 == 1 ? (gen & LB2_64) >> 5 : (gen & LB1_64) >> 6;
				result |= gen;
			}

			rayAttacks[2][i] = result;

			// right backwards
			gen = 1ull << i;
			result = 0;

			for(int j = 0; j < 10; j++)
			{
				int idx = LSB64(gen) / 5;
				gen = idx % 2 == 1 ? (gen & RB2_64) >> 4 : (gen & RB1_64) >> 5;
				result |= gen;
			}

			rayAttacks[3][i] = result;
		} // for

	}

	void DumpBitBoard(int logId, uint64 bb)
	{
		bool bPrintBefore = true;
		for(int i = 49; i >= 0; i-=5)
		{
			for(int j = i - 4; j <= i; j++)
			{
				if(bPrintBefore)
					LogMessage(logId, " ");

				int64 bit = bb & (1ull << j);
				if(bit)
					LogMessage(logId, "1");
				else
					LogMessage(logId, "0");

				if(! bPrintBefore)
					LogMessage(logId, " ");
			}

			LogMessage(logId, "\n");
			bPrintBefore =  !bPrintBefore;
		}

		LogMessage(logId, "\n");
	}


	void DumpRayAttacks()
	{
		FILE* fp = NULL;
		int logId = LogInit("c:\\Log\\rayattacks64.txt");

		for(int i = 0; i < 50; i++)	
		{
			LOG_MSG(logId, "Position %d\n", i);

			for(int dir = 0; dir < 4; dir++)
			{
				LOG_MSG(logId, "Direction %d\n", dir);
				DumpBitBoard(logId, rayAttacks[dir][i]);
			}
		}
	}


	void InitBitBoardGenerator()
	{
		PrecalculateRayAttacks();
	}


	  ///////////////////////////////////////////////////////////////////////////////////////////////
	 // Generation of normal moves
	////////////////////////////////////////////////////////////////////////////////////////////////

	 // Man moves
	////////////////////////////////////////////

	void MakeWhiteManMoves(BitBoard64* bb, BitBoardMove64* movelist, int& index, uint64 free)
	{
		int n = index;
		uint64 tmp;
		int64 m;

		if(bb->wm)
		{
			/* moves left forwards */
			/* I: columns 1357: just moves */
			m=((bb->wm&LF1_64)<<4)&free;
			/* now m contains a bit for every free square where a black man can move*/
			while(m)
			{
   				tmp=(m&-m); /* least significant bit of m */
				tmp=tmp|(tmp>>4); /* square where man came from */
				movelist[n].wm=tmp&NWBR_64; /* NWBR: not white back rank */
				movelist[n].wk=tmp&WBR_64; /*if stone moves to WBR (white back rank) it's a king*/
				movelist[n].bm=0;
				movelist[n].bk=0;
				n++;
      			m=m&(m-1);   /* clears least significant bit of m */
      		}

			 /* II: columns 2468 */
			m=((bb->wm&LF2_64)<<5)&free;
			while(m)
   			{
				tmp=(m&-m);
				tmp=tmp|(tmp>>5);
				movelist[n].wm=tmp;
				movelist[n].wk=0;
				movelist[n].bm=0;
				movelist[n].bk=0;
				n++;
      			m=m&(m-1);
      		}
			 /* moves right forwards */
			 /* I: columns 1357 :just moves*/
			 m=((bb->wm&RF1_64)<<5)&free;
			 while(m)
   			{
				tmp=(m&-m);
				tmp=tmp|(tmp>>5);
				movelist[n].wm=tmp&NWBR_64;
				movelist[n].wk=tmp&WBR_64;
				movelist[n].bm=0;
				movelist[n].bk=0;
				n++;
      			m=m&(m-1);
      		}

			 /* II: columns 2468 */
			m=((bb->wm&RF2_64)<<6)&free;
			while(m)
   			{
				tmp=(m&-m);
				tmp=tmp|(tmp>>6);
				movelist[n].wm=tmp;
				movelist[n].wk=0;
				movelist[n].bm=0;
				movelist[n].bk=0;
				n++;
      			m=m&(m-1);
      		}
		} // if

		index = n;
	}

	void MakeBlackManMoves(BitBoard64* bb, BitBoardMove64* movelist, int& index, uint64 free)
	{
		int n = index;
		uint64 tmp;
		int64 m;

		if(bb->bm)
		{
			/* moves left backwards */
			/* II: columns 2468 ;just moves*/
			m=((bb->bm&LB2_64)>>5)&free;
			while(m)
   			{
				tmp=(m&-m);
				tmp=tmp|(tmp<<5);
				movelist[n].wm=0;
				movelist[n].wk=0;
				movelist[n].bm=tmp&NBBR_64;
				movelist[n].bk=tmp&BBR_64;
				n++;
      			m=m&(m-1);
      		}
        
			/* I: columns 1357 */
			m=((bb->bm&LB1_64)>>6)&free;
			/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				tmp=tmp|(tmp<<6);
				movelist[n].wm=0;
				movelist[n].wk=0;
				movelist[n].bm=tmp;
				movelist[n].bk=0;
      			n++;
      			m=m&(m-1);   /* clears least significant bit of m */
      		}

			/* moves right backwards */

			/* II: columns 2468 : just the moves*/
			m=((bb->bm&RB2_64)>>4)&free;
			while(m)
   			{
				tmp=(m&-m);
				tmp=tmp|(tmp<<4);
				movelist[n].wm=0;
				movelist[n].wk=0;
				movelist[n].bm=tmp&NBBR_64;
				movelist[n].bk=tmp&BBR_64;
				n++;
      			m=m&(m-1);
      		}
			/* I: columns 1357 */
			m=((bb->bm&RB1_64)>>5)&free;
			while(m)
   			{
				tmp=(m&-m);
				tmp=tmp|(tmp<<5);
				movelist[n].wm=0;
				movelist[n].wk=0;
				movelist[n].bm=tmp;
				movelist[n].bk=0;
      			n++;
      			m=m&(m-1);
      		}
		} // if

		index  = n;
	}


	 // King moves
	////////////////////////////////////////////

	void MakeWhiteKingMoves(BitBoard64* bb, BitBoardMove64* movelist, int& index, uint64 free)
	{
		int i = index;
		uint64 ray, blocker;
		uint64 occupied = ~free;
		uint64 tmp;
		int blockerSquare;
	
		int64 wk = bb->wk;
		while(wk)
		{
			int wkpos = LSB64(wk); // get field of white king

			for(int j = 0; j < 4; j++)
			{
				ray = rayAttacks[j][wkpos];
				blocker = ray & occupied;
				if(blocker)
				{
					blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);
					ray ^= rayAttacks[j][blockerSquare] | (1ull << blockerSquare);
				}

				while(ray)
				{
					tmp = 1ull << wkpos;
					tmp |= 1ull << LSB64(ray);
					movelist[i].wk = tmp;
					movelist[i].bk = 0;
					movelist[i].wm = 0;
					movelist[i].bm = 0;
					i++;

					ray = ray & (ray - 1); // delete least significant bit
				}
			} // for


			wk = wk &  (wk - 1); // delete least significant bit
		} // while

		index = i;
	}

	void MakeBlackKingMoves(BitBoard64* bb, BitBoardMove64* movelist, int& index, uint64 free)
	{
		int i = index;
		uint64 ray, blocker;
		uint64 occupied = ~free;
		uint64 tmp;
		int blockerSquare;
	
		int64 bk = bb->bk;
		while(bk)
		{
			int bkpos = LSB64(bk); // get field of white king

			for(int j = 0; j < 4; j++)
			{
				ray = rayAttacks[j][bkpos];
				blocker = ray & occupied;
				if(blocker)
				{
					blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);
					ray ^= rayAttacks[j][blockerSquare] | (1ull << blockerSquare);
				}

				while(ray)
				{
					tmp = 1ull << bkpos;
					tmp |= 1ull << LSB64(ray);
					movelist[i].bk = tmp;
					movelist[i].wk = 0;
					movelist[i].wm = 0;
					movelist[i].bm = 0;
					i++;

					ray = ray & (ray - 1); // delete least significant bit
				}
			} // for


			bk = bk &  (bk - 1); // delete least significant bit
		} // while

		index = i;
	}

	int MakeMoveList(BitBoard64 *bb, BitBoardMove64* movelist, bool bWhite)
	{
		int index = 0;
		uint64 free=~(bb->bm|bb->bk|bb->wm|bb->wk);
   
		if(bWhite == true)
		{
			MakeWhiteKingMoves(bb, movelist, index, free);
			MakeWhiteManMoves(bb, movelist, index, free);     
		}
		else
		{
			MakeBlackKingMoves(bb, movelist, index, free);
			MakeBlackManMoves(bb, movelist, index, free);
		}

		return index;
	}


      ////////////////////////////////////////////////////////////////////////////////////////////////
	 // Generation of normal moves
	////////////////////////////////////////////////////////////////////////////////////////////////


	 // Man captures
	////////////////////////////////////////////////////////

	void WhiteManCapture1(BitBoard64 *p, BitBoardMove64* movelist,int *n, BitBoardMove64 *partial, uint64 square)
	{
		/* partial move has already been executed. seek LFJ1 and RFJ1 */
		uint64 m,free,black;
		bool found=false;
		BitBoardMove64 next_partial,whole_partial;
		BitBoard64 q;
		partial->length++;

		free=~(p->bm|p->bk|p->wm|p->wk);
		black=p->bm|p->bk;
	   /* left forward jump */
		m=((((square&LFJ1_64)<<4)&black)<<5)&free;
		if(m)
   		{
			next_partial.wm=(m|(m>>9));
			next_partial.wk=0;
			next_partial.bm=(m>>5)&p->bm;
			next_partial.bk=(m>>5)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture1(&q,movelist,n,&whole_partial,m);
     
			found=true;
		 } // if

		/* right forward jump */
		m=((((square&RFJ1_64)<<5)&black)<<6)&free;
		if(m)
		{
			next_partial.wm=(m|(m>>11));
			next_partial.wk=0;
			next_partial.bm=(m>>6)&p->bm;
			next_partial.bk=(m>>6)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture1(&q,movelist,n,&whole_partial,m);
      
			found=true;
		}
		/* left backward jump */
		m=((((square&LBJ1_64)>>6)&black)>>5)&free;
		if(m)
   		{
			next_partial.wm=(m|(m<<11));
			next_partial.wk=0;
			next_partial.bm=(m<<5)&p->bm;
			next_partial.bk=(m<<5)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture1(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}

	   /* right backward jump */
		m=((((square&RBJ1_64)>>5)&black)>>4)&free;
		if(m)
   		{
			next_partial.wm=(m|(m<<9));
			next_partial.wk=0;
			next_partial.bm=(m<<4)&p->bm;
			next_partial.bk=(m<<4)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture1(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}


		if(!found)
   		{
			partial->wk = partial->wm & WBR_64;
			partial->wm = partial->wm & NWBR_64;
			movelist[*n]=*partial;
			movelist[*n].length--;
			(*n)++;
		}

		partial->length--;
	}

	void WhiteManCapture2(BitBoard64 *p, BitBoardMove64* movelist,int *n, BitBoardMove64 *partial, uint64 square)
	{
		uint64 m,free,black;
		BitBoardMove64 next_partial,whole_partial;
		bool found=false;
		BitBoard64 q;
		partial->length++;


		free=~(p->bm|p->bk|p->wm|p->wk);
		black=p->bm|p->bk;
	   /* left forward jump */
		m=((((square&LFJ2_64)<<5)&black)<<4)&free;
		if(m)
   		{
			next_partial.wm=(m|(m>>9));
			next_partial.wk=0;
			next_partial.bm=(m>>4)&p->bm;
			next_partial.bk=(m>>4)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=true;
		}

	   /* right forward jump */
		m=((((square&RFJ2_64)<<6)&black)<<5)&free;
		if(m)
   		{
			next_partial.wm=(m|(m>>11));
			next_partial.wk=0;
			next_partial.bm=(m>>5)&p->bm;
			next_partial.bk=(m>>5)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=true;
		}

		m=((((square&LBJ2_64)>>5)&black)>>6)&free;
		if(m)
   		{
			next_partial.wm=(m|(m<<11));
			next_partial.wk=0;
			next_partial.bm=(m<<6)&p->bm;
			next_partial.bk=(m<<6)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}

	   /* right backward jump */
		m=((((square&RBJ2_64)>>4)&black)>>5)&free;
		if(m)
   		{
			next_partial.wm=(m|(m<<9));
			next_partial.wk=0;
			next_partial.bm=(m<<5)&p->bm;
			next_partial.bk=(m<<5)&p->bk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			WhiteManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}

		if(!found)
   		{
			partial->wk = partial->wm & WBR_64;
			partial->wm = partial->wm & NWBR_64;
			movelist[*n]=*partial;
			movelist[*n].length--;
			(*n)++;
		}

		partial->length--;
	}

	void BlackManCapture1(BitBoard64 *p, BitBoardMove64* movelist,int *n, BitBoardMove64* partial, uint64 square)
	{
		uint64 m,free,white;
		BitBoardMove64 next_partial,whole_partial;
		int found=0;
		BitBoard64 q;
		partial->length++;

		free=~(p->bm|p->bk|p->wm|p->wk);
		white=p->wm|p->wk;
		/* left backward jump */
		m=((((square&LBJ1_64)>>6)&white)>>5)&free;
		if(m)
   		{
			next_partial.bm=(m|(m<<11));
			next_partial.bk=0;
			next_partial.wm=(m<<5)&p->wm;
			next_partial.wk=(m<<5)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture1(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}

	   /* right backward jump */
		m=((((square&RBJ1_64)>>5)&white)>>4)&free;
		if(m)
   		{
			next_partial.bm=(m|(m<<9));
			next_partial.bk=0;
			next_partial.wm=(m<<4)&p->wm;
			next_partial.wk=(m<<4)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture1(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}
	   /* left forward jump */
		m=((((square&LFJ1_64)<<4)&white)<<5)&free;
		if(m)
   		{
			next_partial.bm=(m|(m>>9));
			next_partial.bk=0;
			next_partial.wm=(m>>5)&p->wm;
			next_partial.wk=(m>>5)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture1(&q,movelist,n,&whole_partial,m);
     
			found=true;
		 } // if

		/* right forward jump */
		m=((((square&RFJ1_64)<<5)&white)<<6)&free;
		if(m)
		{
			next_partial.bm=(m|(m>>11));
			next_partial.bk=0;
			next_partial.wm=(m>>6)&p->wm;
			next_partial.wk=(m>>6)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture1(&q,movelist,n,&whole_partial,m);
      
			found=true;
		}

		if(!found)
   		{
			partial->bk = partial->bm & BBR_64;
			partial->bm = partial->bm & NBBR_64;
			movelist[*n]=*partial;
			movelist[*n].length--;
			(*n)++;
		}

		partial->length--;
	}

	void BlackManCapture2(BitBoard64 *p, BitBoardMove64* movelist,int *n, BitBoardMove64 *partial, uint64 square)
	{
		uint64 m,free,white;
		BitBoardMove64 next_partial,whole_partial;
		int found=0;
		BitBoard64 q;
		partial->length++;
	
		free=~(p->bm|p->bk|p->wm|p->wk);
		white=p->wm|p->wk;
	   /* left backward jump */
		m=((((square&LBJ2_64)>>5)&white)>>6)&free;
		if(m)
   		{
			next_partial.bm=(m|(m<<11));
			next_partial.bk=0;
			next_partial.wm=(m<<6)&p->wm;
			next_partial.wk=(m<<6)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}

	   /* right backward jump */
		m=((((square&RBJ2_64)>>4)&white)>>5)&free;
		if(m)
   		{
			next_partial.bm=(m|(m<<9));
			next_partial.bk=0;
			next_partial.wm=(m<<5)&p->wm;
			next_partial.wk=(m<<5)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=1;
		}
	   /* left forward jump */
		m=((((square&LFJ2_64)<<5)&white)<<4)&free;
		if(m)
   		{
			next_partial.bm=(m|(m>>9));
			next_partial.bk=0;
			next_partial.wm=(m>>4)&p->wm;
			next_partial.wk=(m>>4)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;
			BlackManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=true;
		}

	   /* right forward jump */
		m=((((square&RFJ2_64)<<6)&white)<<5)&free;
		if(m)
   		{
			next_partial.bm=(m|(m>>11));
			next_partial.bk=0;
			next_partial.wm=(m>>5)&p->wm;
			next_partial.wk=(m>>5)&p->wk;
			q.bm=p->bm^next_partial.bm;
			q.bk=p->bk^next_partial.bk;
   			q.wm=p->wm^next_partial.wm;
   			q.wk=p->wk^next_partial.wk;
      
			whole_partial.bm=partial->bm^next_partial.bm;
			whole_partial.bk=partial->bk^next_partial.bk;
			whole_partial.wm=partial->wm^next_partial.wm;
			whole_partial.wk=partial->wk^next_partial.wk;
			whole_partial.length = partial->length;

			BlackManCapture2(&q,movelist,n,&whole_partial,m);
      
			found=true;
		}

		if(!found)
		{
			partial->bk = partial->bm & BBR_64;
			partial->bm = partial->bm & NBBR_64;
			movelist[*n]=*partial;
			movelist[*n].length--;
			(*n)++;
		}

		partial->length--;
	}

	void MakeWhiteManCaptures(BitBoard64* p, BitBoardMove64* movelist, int& n)
	{
		int64 m;
		uint64 tmp;
		BitBoardMove64 partial;
		uint64 black = 0, black2, free2;
		uint64 free = ~(p->bm|p->bk|p->wm|p->wk);
		BitBoard64 q;
		partial.length = 1;

		if(p->wm)
		{
			black=p->bm|p->bk;
      		m=((((p->wm&LFJ2_64)<<5)&black)<<4)&free;
			while(m)
   			{
				/* find a move */
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp>>9));  /* NWBR: not white back rank */
				partial.wk=0;
				partial.bm=(tmp>>4)&p->bm;
				partial.bk=(tmp>>4)&p->bk;
				/* toggle it */
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
				/* recursion */
				/* only if black has another capture move! */
				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);			
				if ( (((((tmp&LFJ2_64)<<5)&black2)<<4)&free2) | (((((tmp&RFJ2_64)<<6)&black2)<<5)&free2)
					| (((((tmp&LBJ2_64)>>5)&black2)>>6)&free2) | (((((tmp&RBJ2_64)>>4)&black2)>>5)&free2))
            		WhiteManCapture2(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
				/* clears least significant bit of m, associated with that move. */
      			m=m&(m-1);
  			}

			m=((((p->wm&LFJ1_64)<<4)&black)<<5)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp>>9));
				partial.wk=0;
				partial.bm=(tmp>>5)&p->bm;
				partial.bk=(tmp>>5)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            

				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LFJ1_64)<<4)&black2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&black2)<<6)&free2 )
					| (((((tmp&LBJ1_64)>>6)&black2)>>5)&free2) | (((((tmp&RBJ1_64)>>5)&black2)>>4)&free2) )
            		WhiteManCapture1(&q,movelist,&n,&partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			/* jumps right forwards with men*/
			m=((((p->wm&RFJ2_64)<<6)&black)<<5)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp>>11));
				partial.wk=0;
				partial.bm=(tmp>>5)&p->bm;
				partial.bk=(tmp>>5)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            
				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LFJ2_64)<<5)&black2)<<4)&free2 ) | ( ((((tmp&RFJ2_64)<<6)&black2)<<5)&free2 )
					| (((((tmp&LBJ2_64)>>5)&black2)>>6)&free2) | (((((tmp&RBJ2_64)>>4)&black2)>>5)&free2) )
            		WhiteManCapture2(&q,movelist,&n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			m=((((p->wm&RFJ1_64)<<5)&black)<<6)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=tmp|(tmp>>11);
				partial.wk=0;
				partial.bm=(tmp>>6)&p->bm;
				partial.bk=(tmp>>6)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            
				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LFJ1_64)<<4)&black2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&black2)<<6)&free2 )
					| (((((tmp&LBJ1_64)>>6)&black2)>>5)&free2) | (((((tmp&RBJ1_64)>>5)&black2)>>4)&free2))
            		WhiteManCapture1(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}
      		/* jumps left backwards with men*/
			m=((((p->wm&LBJ1_64)>>6)&black)>>5)&free;
      		/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp<<11));
				partial.wk=0;
				partial.bm=(tmp<<5)&p->bm;
				partial.bk=(tmp<<5)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
				/* only if white has another capture move! */
				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				// TODO: jumps forward
				if ( ( ((((tmp&LBJ1_64)>>6)&black2)>>5)&free2) | ( ((((tmp&RBJ1_64)>>5)&black2)>>4)&free2 )
					| ( ((((tmp&LFJ1_64)<<4)&black2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&black2)<<6)&free2 ))
            		WhiteManCapture1(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
				m=m&(m-1);   /* clears least significant bit of m */
			}

			m=((((p->wm&LBJ2_64)>>5)&black)>>6)&free;
      		/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp<<11));
				partial.wk=0;
				partial.bm=(tmp<<6)&p->bm;
				partial.bk=(tmp<<6)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;

				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ2_64)>>5)&black2)>>6)&free2) | ( ((((tmp&RBJ2_64)>>4)&black2)>>5)&free2 )
					| ( ((((tmp&LFJ2_64)<<5)&black2)<<4)&free2 ) | ( ((((tmp&RFJ2_64)<<6)&black2)<<5)&free2 ) )
            		WhiteManCapture2(&q,movelist,&n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			/* jumps right backwards with men*/
      		m=((((p->wm&RBJ1_64)>>5)&black)>>4)&free;
      		/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp<<9));
				partial.wk=0;
				partial.bm=(tmp<<4)&p->bm;
				partial.bk=(tmp<<4)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;

				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ1_64)>>6)&black2)>>5)&free2) | ( ((((tmp&RBJ1_64)>>5)&black2)>>4)&free2 )
					| ( ((((tmp&LFJ1_64)<<4)&black2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&black2)<<6)&free2 ))
            		WhiteManCapture1(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			m=((((p->wm&RBJ2_64)>>4)&black)>>5)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.wm=(tmp|(tmp<<9));
				partial.wk=0;
				partial.bm=(tmp<<5)&p->bm;
				partial.bk=(tmp<<5)&p->bk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            
				black2=p->bm|p->bk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ2_64)>>5)&black2)>>6)&free2) | ( ((((tmp&RBJ2_64)>>4)&black2)>>5)&free2 )
					| ( ((((tmp&LFJ2_64)<<5)&black2)<<4)&free2 ) | ( ((((tmp&RFJ2_64)<<6)&black2)<<5)&free2 ))
            		WhiteManCapture2(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.wk = partial.wm & WBR_64;
					partial.wm = partial.wm & NWBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}
		} // if
	}


	void MakeBlackManCaptures(BitBoard64* p, BitBoardMove64* movelist, int& n)
	{
		int64 m;
		uint64 tmp;
		BitBoardMove64 partial;
		uint64 white = 0, white2, free2;
		uint64 free = ~(p->bm|p->bk|p->wm|p->wk);
		BitBoard64 q;
		partial.length = 1;

		if(p->bm)
		{
			white=p->wm|p->wk;
			m=((((p->bm&LFJ2_64)<<5)&white)<<4)&free;
			while(m)
   			{
				/* find a move */
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp>>9));  /* NWBR: not white back rank */
				partial.bk=0;
				partial.wm=(tmp>>4)&p->wm;
				partial.wk=(tmp>>4)&p->wk;
				/* toggle it */
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
				/* recursion */
				/* only if black has another capture move! */
				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);			
				if ( (((((tmp&LFJ2_64)<<5)&white2)<<4)&free2) | (((((tmp&RFJ2_64)<<6)&white2)<<5)&free2)
					| (((((tmp&LBJ2_64)>>5)&white2)>>6)&free2) | (((((tmp&RBJ2_64)>>4)&white2)>>5)&free2))
            		BlackManCapture2(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
				/* clears least significant bit of m, associated with that move. */
      			m=m&(m-1);
  			}

			m=((((p->bm&LFJ1_64)<<4)&white)<<5)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp>>9));
				partial.bk=0;
				partial.wm=(tmp>>5)&p->wm;
				partial.wk=(tmp>>5)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            

				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LFJ1_64)<<4)&white2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&white2)<<6)&free2 )
					| (((((tmp&LBJ1_64)>>6)&white2)>>5)&free2) | (((((tmp&RBJ1_64)>>5)&white2)>>4)&free2) )
            		BlackManCapture1(&q,movelist,&n,&partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			/* jumps right forwards with men*/
			m=((((p->bm&RFJ2_64)<<6)&white)<<5)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp>>11));
				partial.bk=0;
				partial.wm=(tmp>>5)&p->wm;
				partial.wk=(tmp>>5)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            
				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LFJ2_64)<<5)&white2)<<4)&free2 ) | ( ((((tmp&RFJ2_64)<<6)&white2)<<5)&free2 )
					| (((((tmp&LBJ2_64)>>5)&white2)>>6)&free2) | (((((tmp&RBJ2_64)>>4)&white2)>>5)&free2) )
            		BlackManCapture2(&q,movelist,&n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			m=((((p->bm&RFJ1_64)<<5)&white)<<6)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=tmp|(tmp>>11);
				partial.bk=0;
				partial.wm=(tmp>>6)&p->wm;
				partial.wk=(tmp>>6)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            
				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LFJ1_64)<<4)&white2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&white2)<<6)&free2 )
					| (((((tmp&LBJ1_64)>>6)&white2)>>5)&free2) | (((((tmp&RBJ1_64)>>5)&white2)>>4)&free2))
            		BlackManCapture1(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}
      		/* jumps left backwards with men*/
			m=((((p->bm&LBJ1_64)>>6)&white)>>5)&free;
      		/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp<<11));
				partial.bk=0;
				partial.wm=(tmp<<5)&p->wm;
				partial.wk=(tmp<<5)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
				/* only if white has another capture move! */
				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ1_64)>>6)&white2)>>5)&free2) | ( ((((tmp&RBJ1_64)>>5)&white2)>>4)&free2 )
					| ( ((((tmp&LFJ1_64)<<4)&white2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&white2)<<6)&free2 ))
            		BlackManCapture1(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
				m=m&(m-1);   /* clears least significant bit of m */
			}

			m=((((p->bm&LBJ2_64)>>5)&white)>>6)&free;
      		/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp<<11));
				partial.bk=0;
				partial.wm=(tmp<<6)&p->wm;
				partial.wk=(tmp<<6)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;

				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ2_64)>>5)&white2)>>6)&free2) | ( ((((tmp&RBJ2_64)>>4)&white2)>>5)&free2 )
					| ( ((((tmp&LFJ2_64)<<5)&white2)<<4)&free2 ) | ( ((((tmp&RFJ2_64)<<6)&white2)<<5)&free2 ) )
            		BlackManCapture2(&q,movelist,&n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			/* jumps right backwards with men*/
			m=((((p->bm&RBJ1_64)>>5)&white)>>4)&free;
      		/* now m contains a bit for every free square where a white man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp<<9));
				partial.bk=0;
				partial.wm=(tmp<<4)&p->wm;
				partial.wk=(tmp<<4)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;

				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ1_64)>>6)&white2)>>5)&free2) | ( ((((tmp&RBJ1_64)>>5)&white2)>>4)&free2 )
					| ( ((((tmp&LFJ1_64)<<4)&white2)<<5)&free2 ) | ( ((((tmp&RFJ1_64)<<5)&white2)<<6)&free2 ))
            		BlackManCapture1(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}

			m=((((p->bm&RBJ2_64)>>4)&white)>>5)&free;
      		/* now m contains a bit for every free square where a black man can move*/
			while(m)
   			{
				tmp=(m&-m); /* least significant bit of m */
				partial.bm=(tmp|(tmp<<9));
				partial.bk=0;
				partial.wm=(tmp<<5)&p->wm;
				partial.wk=(tmp<<5)&p->wk;
				q.bm=p->bm^partial.bm;
   				q.bk=p->bk^partial.bk;
   				q.wm=p->wm^partial.wm;
   				q.wk=p->wk^partial.wk;
            
				white2=p->wm|p->wk;
				free2=~(p->wm|p->wk|p->bm|p->bk);
				if ( ( ((((tmp&LBJ2_64)>>5)&white2)>>6)&free2) | ( ((((tmp&RBJ2_64)>>4)&white2)>>5)&free2 )
					| ( ((((tmp&LFJ2_64)<<5)&white2)<<4)&free2 ) | ( ((((tmp&RFJ2_64)<<6)&white2)<<5)&free2 ))
            		BlackManCapture2(&q,movelist, &n, &partial,tmp);
				else
				{
					partial.bk = partial.bm & BBR_64;
					partial.bm = partial.bm & NBBR_64;
      				movelist[n]=partial;
      				n++;
				}
            
      			m=m&(m-1);   /* clears least significant bit of m */
			}
		} // if
	}



	 // King captures
	////////////////////////////////////////////////////////

	bool MakeWhiteKingCaptures(BitBoard64* bb, BitBoardMove64* movelist, int& index, int ignoreDirection = -1, uint64 square = 255)
	{
		int i = index;
		uint64 ray, blocker, jumpedPattern;
		uint64 occupied = bb->wm | bb->bm | bb->wk | bb->bk;
		uint64 tmp;
		int64 blockerSquare, jumpedSquare;
		bool bFound = false;
		BitBoardMove64 partial;
		BitBoard64 q;

	
		uint64 wk = bb->wk;
		uint64 black = bb->bm | bb->bk;
		uint64 jumpedBlack = 0;

		if(square != 255)
			wk = 1ull << square;


		while(wk)
		{
			int wkpos = LSB64(wk); // get field of white king

			for(int j = 0; j < 4; j++)
			{
				// for multiple jumps ignore direction back
				if(j == ignoreDirection)
					continue;
				ray = rayAttacks[j][wkpos];

				jumpedBlack = ray & black;
				if(! jumpedBlack) // no jumped figure, continue
					continue; 
				jumpedSquare = j < 2 ? LSB64(jumpedBlack) : MSB64(jumpedBlack);
				blocker = ray & occupied;
				blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);

				// if blocker square earlier, ignore
				if(j < 2)
				{
					if(blockerSquare < jumpedSquare)
						continue;
				}
				else
				{
					if(blockerSquare > jumpedSquare)
						continue;
				}

				// get next blocker after jump
				ray = rayAttacks[j][jumpedSquare];
				blocker = ray & occupied;
				if(blocker)
				{
					blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);			
					ray ^= rayAttacks[j][blockerSquare]  | (1ull << blockerSquare);
				}

				jumpedPattern = 1ull << jumpedSquare;

				bool bMultipleJump = false;
				int startI = i;
				while(ray)
				{
					// record partial move
					tmp = 1ull << wkpos;
					uint64 finalSquare = LSB64(ray);
					tmp |= 1ull << finalSquare;
					partial.wk = tmp;
					partial.bk = bb->bk & jumpedPattern;
					partial.wm = bb->wm & jumpedPattern;
					partial.bm = bb->bm & jumpedPattern;
					partial.length = 1;


					// prepare next position
					q.wk = bb->wk ^ partial.wk;
					q.bk = bb->bk ^ partial.bk;
					q.wm = bb->wm ^ partial.wm;
					q.bm = bb->bm ^ partial.bm;

					int oldI = i;			
					if(MakeWhiteKingCaptures(&q, movelist, i, 3 - j, finalSquare) == false)
					{
						if(bMultipleJump == false)
						{
							movelist[i++] = partial;
							bFound = true;
						}
					} // if
					else if(i > oldI)
					{
						int k = oldI;
						while(k < i)
						{
							movelist[k].wm ^= partial.wm;
							movelist[k].bm ^= partial.bm;
							movelist[k].wk ^= partial.wk;
							movelist[k].bk ^= partial.bk;
							movelist[k].length++;
							k++;
						}				
						if(bMultipleJump == false)
						{
							memcpy(&movelist[startI], &movelist[oldI], (i - oldI) * sizeof(BitBoardMove64));
							i = startI + (i - oldI);
						}

					
						bMultipleJump = true;
						bFound = true;
					}


					ray = ray & (ray - 1); // delete least significant bit
				}
			} // for


			wk = wk &  (wk - 1); // delete least significant bit
		} // while

		index = i;

		return bFound;
	}


	bool MakeBlackKingCaptures(BitBoard64* bb, BitBoardMove64* movelist, int& index, 
								int ignoreDirection = -1, uint64 square = 255)
	{
		int i = index;
		uint64 ray, blocker, jumpedPattern;
		uint64 occupied = bb->wm | bb->bm | bb->wk | bb->bk;
		uint64 tmp;
		int64 blockerSquare, jumpedSquare;
		bool bFound = false;
		BitBoardMove64 partial;
		BitBoard64 q;

	
		uint64 bk = bb->bk;
		uint64 white = bb->wm | bb->wk;
		uint64 jumpedWhite = 0;

		if(square != 255)
			bk = 1ull << square;

		while(bk)
		{
			int bkpos = LSB64(bk); // get field of white king

			for(int j = 0; j < 4; j++)
			{
				// for multiple jumps ignore direction back
				if(j == ignoreDirection)
					continue;
				ray = rayAttacks[j][bkpos];

				jumpedWhite = ray & white;
				if(! jumpedWhite) // no jumped figure, continue
					continue; 
				jumpedSquare = j < 2 ? LSB64(jumpedWhite) : MSB64(jumpedWhite);
				blocker = ray & occupied;
				blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);

				// if blocker square earlier, ignore
				if(j < 2)
				{
					if(blockerSquare < jumpedSquare)
						continue;
				}
				else
				{
					if(blockerSquare > jumpedSquare)
						continue;
				}

				// get next blocker after jump
				ray = rayAttacks[j][jumpedSquare];
				blocker = ray & occupied;
				if(blocker)
				{
					blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);			
					ray ^= (rayAttacks[j][blockerSquare]) | (1ull << blockerSquare);
				}

				jumpedPattern = 1ull << jumpedSquare;

				bool bMultipleJump = false;
				int startI = i;
				while(ray)
				{
					// record partial move
					tmp = 1ull << bkpos;
					uint64 finalSquare = LSB64(ray);
					tmp |= 1ull << finalSquare;
					partial.bk = tmp;
					partial.wk = bb->wk & jumpedPattern;
					partial.wm = bb->wm & jumpedPattern;
					partial.bm = bb->bm & jumpedPattern;
					partial.length = 1;

					// prepare next position
					q.wk = bb->wk ^ partial.wk;
					q.bk = bb->bk ^ partial.bk;
					q.wm = bb->wm ^ partial.wm;
					q.bm = bb->bm ^ partial.bm;

					int oldI = i;
					if(MakeBlackKingCaptures(&q, movelist, i, 3 - j, finalSquare) == false)
					{
						if(bMultipleJump == false)
						{
							movelist[i++] = partial;
							bFound = true;
						}
					} // if
					else if(i > oldI)
					{
						int k = oldI;
						while(k < i)
						{
							movelist[k].wm ^= partial.wm;
							movelist[k].bm ^= partial.bm;
							movelist[k].wk ^= partial.wk;
							movelist[k].bk ^= partial.bk;
							movelist[k].length++;
							k++;
						}				
						if(bMultipleJump == false)
						{
							memcpy(&movelist[startI], &movelist[oldI], (i - oldI) * sizeof(BitBoardMove64));
							i = startI + (i - oldI);
						}

					
						bMultipleJump = true;
						bFound = true;
					}

					ray = ray & (ray - 1); // delete least significant bit
				}
			} // for


			bk = bk &  (bk - 1); // delete least significant bit
		} // while

		index = i;

		return bFound;
	}

	 // Function for finding the longest moves
	/////////////////////////////////////////////////////////////////////////////////////////////
	void CaptureShiftingProcess(BitBoardMove64* bb, int& count)
	{
		int c = count;
		
		// find longest move
		uint8 moveLength = 0;
		for(int i = 0; i < c; i++)
		{
			register BitBoard64* pMove = bb + i;
			if( pMove->length > moveLength)
				moveLength = pMove->length;
		} // for

		// shift the moves to the beginning
		for(int i = 0; i < c; i++)
		{
			register BitBoard64* pMove = bb + i;
			
			// if move shorter, do shift
			if(pMove->length < moveLength)
			{
				memcpy(pMove, pMove + 1, sizeof(BitBoard64) * (c - i - 1));
				c--;
				i--;
			}		
		}

		// set the new move count
		count = c;
	}

	// function for making captures
	int MakeCaptureList(BitBoard64 *bb, BitBoardMove64* movelist, bool bWhite)
	{
		int index = 0;
   
		// resolve captures according to the side to move
		if(bWhite == true)
		{
			MakeWhiteKingCaptures(bb, movelist, index);
			MakeWhiteManCaptures(bb, movelist, index);
		}
		else
		{
			MakeBlackKingCaptures(bb, movelist, index);
			MakeBlackManCaptures(bb, movelist, index);
		}

		// find the longest captures and do move shifting
		CaptureShiftingProcess(movelist, index);

		return index;
	}

      ////////////////////////////////////////////////////////////////////////////////////////////////////////////
	 // Test capture functions
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////

	bool TestMenCapture(BitBoard64 *p, bool bWhite)
	{
		uint64 black,white,free,m;

		if (bWhite == true)
		{
			black=p->bm|p->bk;
			white=p->wm|p->wk;
			free=~(black|white);
		
			m =((((white&LFJ2_64)<<5)&black)<<4);
			m|=((((white&LFJ1_64)<<4)&black)<<5);
			m|=((((white&RFJ1_64)<<5)&black)<<6);
			m|=((((white&RFJ2_64)<<6)&black)<<5);
			m|=((((white&LBJ1_64)>>6)&black)>>5);
			m|=((((white&LBJ2_64)>>5)&black)>>6);
			m|=((((white&RBJ1_64)>>5)&black)>>4);
			m|=((((white&RBJ2_64)>>4)&black)>>5);

			if(m & free)
				return true;
			return false;
		}
		else
		{
			black=p->bm|p->bk;
			white=p->wm|p->wk;
			free=~(black|white);

			m =((((black&LBJ1_64)>>6)&white)>>5);
			m|=((((black&LBJ2_64)>>5)&white)>>6);
			m|=((((black&RBJ1_64)>>5)&white)>>4);
			m|=((((black&RBJ2_64)>>4)&white)>>5);
			m|=((((black&LFJ2_64)<<5)&white)<<4);
			m|=((((black&LFJ1_64)<<4)&white)<<5);
			m|=((((black&RFJ1_64)<<5)&white)<<6);
			m|=((((black&RFJ2_64)<<6)&white)<<5);

			if(m & free)
				return true;
			return false;
		}
	}


	bool TestWhiteKingCaptures(BitBoard64* bb)
	{
		uint64 ray, blocker, jumpedPattern;
		uint64 occupied = bb->wm | bb->bm | bb->wk | bb->bk;
		int64 blockerSquare, jumpedSquare;
	
		uint64 wk = bb->wk;
		uint64 black = bb->bm | bb->bk;
		uint64 jumpedBlack = 0;

		while(wk)
		{
			int wkpos = LSB64(wk); // get field of white king

			for(int j = 0; j < 4; j++)
			{
				// for multiple jumps ignore direction back
				ray = rayAttacks[j][wkpos];

				jumpedBlack = ray & black;
				if(! jumpedBlack) // no jumped figure, continue
					continue; 
				jumpedSquare = j < 2 ? LSB64(jumpedBlack) : MSB64(jumpedBlack);
				blocker = ray & occupied;
				blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);

				// if blocker square earlier, ignore
				if(j < 2)
				{
					if(blockerSquare < jumpedSquare)
						continue;
				}
				else
				{
					if(blockerSquare > jumpedSquare)
						continue;
				}

				// get next blocker after jump
				ray = rayAttacks[j][jumpedSquare];
				blocker = ray & occupied;
				if(blocker)
				{
					blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);			
					ray ^= rayAttacks[j][blockerSquare]  | (1ull << blockerSquare);
				}

				jumpedPattern = 1ull << jumpedSquare;

				if(ray)
					return true;
				
			} // for


			wk = wk &  (wk - 1); // delete least significant bit
		} // while

		return false;
	}


	bool TestBlackKingCaptures(BitBoard64* bb)
	{
		uint64 ray, blocker, jumpedPattern;
		uint64 occupied = bb->wm | bb->bm | bb->wk | bb->bk;
		int64 blockerSquare, jumpedSquare;

	
		uint64 bk = bb->bk;
		uint64 white = bb->wm | bb->wk;
		uint64 jumpedWhite = 0;

		while(bk)
		{
			int bkpos = LSB64(bk); // get field of white king

			for(int j = 0; j < 4; j++)
			{
				ray = rayAttacks[j][bkpos];

				jumpedWhite = ray & white;
				if(! jumpedWhite) // no jumped figure, continue
					continue; 
				jumpedSquare = j < 2 ? LSB64(jumpedWhite) : MSB64(jumpedWhite);
				blocker = ray & occupied;
				blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);

				// if blocker square earlier, ignore
				if(j < 2)
				{
					if(blockerSquare < jumpedSquare)
						continue;
				}
				else
				{
					if(blockerSquare > jumpedSquare)
						continue;
				}

				// get next blocker after jump
				ray = rayAttacks[j][jumpedSquare];
				blocker = ray & occupied;
				if(blocker)
				{
					blockerSquare = j < 2 ? LSB64(blocker) : MSB64(blocker);			
					ray ^= (rayAttacks[j][blockerSquare]) | (1ull << blockerSquare);
				}

				jumpedPattern = 1ull << jumpedSquare;

				if(ray)
					return true;
			} // for

			bk = bk &  (bk - 1); // delete least significant bit
		} // while

		return false;
	}



      ////////////////////////////////////////////////////////////////////////////////////////////////////////////
	 // Final function for generating moves
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////

	bool TestJump(BitBoard64* bb, bool bWhite)
	{
		bool bResult = false;

		//WATCH_START(T_TEST_JUMP);

		if(TestMenCapture(bb, bWhite))
			bResult = true;
		else
		{
			if(bWhite && bb->wk )
				bResult = TestWhiteKingCaptures(bb);
			else if(!bWhite && bb->bk)
				bResult = TestBlackKingCaptures(bb);
		}

		//WATCH_END(T_TEST_JUMP);

		return bResult;
	}


	
	int GenerateBitBoardMoves(BitBoard64* bb, bool bWhite, BitBoardMove64* movelist)
	{
		// number of moves
		int count = 0;

		// if side to move has to jump
		if(TestJump(bb, bWhite) == true)
		{
			// make capture list
			count = MakeCaptureList(bb, movelist, bWhite);
		}
		else
		{
			// if normal moves
			count = MakeMoveList(bb, movelist, bWhite);
		}

		// return number of moves added to the list
		return count;
	}

	void ToggleMove(BitBoard64 *p, BitBoardMove64 *m)
	{
		p->bm^=m->bm;
		p->bk^=m->bk;
		p->wm^=m->wm;
		p->wk^=m->wk;
	}


}
